﻿using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;

namespace daStaticAnalyser.Analysers
{
    using daStaticAnalyser.Analysers;
    using daStaticAnalyser;
    using daBase.Objects;
    using daBase.Analyser;
    using daSyntaxAnalyser;
    using daSyntaxAnalyser.SyntaxTree;

    [AnalyserDefaultSettings("Мера Берлингера", "test", 0, "test")]
    class BerlingerAnalyzator : BaseStaticAnalyser
    {
        bool VocSet, LenSet, VolSet, DiffSet, HeffSet;

        Dictionary<String, int> Symbols;
        List<String> SymbolNames;        

        protected override void DoAnalyse(SyntaxTreeArgs e)
        {
            String MethodName = "";
            if (CheckMethod_GetName(e, out MethodName))
            {
                Symbols = new Dictionary<string, int>();
                SymbolNames = new List<string>();
                GetData((e.Element as OuterMethodElement).Body);
                float log2pi = Convert.ToSingle(Math.Log(2,((float)1)/Symbols.Count));
                float M = 0;
                foreach (String Name in SymbolNames)
                {
                    M += Symbols[Name] * log2pi;
                }
                AddMetric("Мера Берлингера",
                            M,
                            MethodName,
                            e.Element.StartInfo.File,
                            e.Element.StartInfo.Line);
            }
        }

        private void GetData(ISyntaxTreeElement Element)
        {
            if (Element == null)
                return;

            if (Element is CaseStatementElement)
            {
                if (Symbols.ContainsKey("case"))
                {
                    Symbols["case"]++;
                }
                else
                {
                    Symbols.Add("case", 1);
                    SymbolNames.Add("case");
                }
            }
            else if (Element is TryStatementElement)
            {
                if (Symbols.ContainsKey("try"))
                {
                    Symbols["try"]++;
                }
                else
                {
                    Symbols.Add("try", 1);
                    SymbolNames.Add("try");
                }
            }
            else if (Element is RepeatStatementElement)
            {
                if (Symbols.ContainsKey("repeat"))
                {
                    Symbols["repeat"]++;
                }
                else
                {
                    Symbols.Add("repeat", 1);
                    SymbolNames.Add("repeat");
                }
            }
            else if (Element is ExceptOnStatementElement)
            {
                if (Symbols.ContainsKey("except"))
                {
                    Symbols["except"]++;
                }
                else
                {
                    Symbols.Add("except", 1);
                    SymbolNames.Add("except");
                }
            }
            else if (Element is ForStatementElement)
            {
                if (Symbols.ContainsKey("for"))
                {
                    Symbols["for"]++;
                }
                else
                {
                    Symbols.Add("for", 1);
                    SymbolNames.Add("for");
                }
            }
            else if (Element is TestStatementElement)
            {
                if (Symbols.ContainsKey("if"))
                {
                    Symbols["if"]++;
                }
                else
                {
                    Symbols.Add("if", 1);
                    SymbolNames.Add("if");
                }
            }
            else if (Element is WhileStatementElement)
            {
                if (Symbols.ContainsKey("while"))
                {
                    Symbols["while"]++;
                }
                else
                {
                    Symbols.Add("while", 1);
                    SymbolNames.Add("while");
                }
            }
            else if (Element is AssignmentElement)
            {
                if (Symbols.ContainsKey(":="))
                {
                    Symbols[":="]++;
                }
                else
                {
                    Symbols.Add(":=", 1);
                    SymbolNames.Add(":=");
                }
            }
            else if (Element is StandartVariableExpressionElement)
            {
                String temp = Element.ToString();
                if (temp.Contains("("))
                {
                    int pos = temp.IndexOf('(');
                    String temp2 = temp.Substring(0,pos);
                    if (Symbols.ContainsKey(temp2))
                    {
                        Symbols[temp2]++;
                    }
                    else
                    {
                        Symbols.Add(temp2, 1);
                        SymbolNames.Add(temp2);
                    }
                }
            }
            else if (Element is BinaryExpressionElement)
            {
                BinaryExpressionElement temp = (Element as BinaryExpressionElement);
                if (Symbols.ContainsKey(temp.Type.Text))
                {
                    Symbols[temp.Type.Text]++;
                }
                else
                {
                    Symbols.Add(temp.Type.Text, 1);
                    SymbolNames.Add(temp.Type.Text);
                }
            }

            foreach (ISyntaxTreeElement element in Element)
            {
                GetData(element);
            }
        }
    }
}
